Browse Source

Merge branch 'dev' into alerting-fixes

Deniz Cengiz 21 hours ago
parent
commit
775e8a3ffd

+ 1 - 1
Config.xcconfig

@@ -19,7 +19,7 @@ TRIO_APP_GROUP_ID = group.org.nightscout.$(DEVELOPMENT_TEAM).trio.trio-app-group
 
 
 // The developers set the version numbers, please leave them alone
 // The developers set the version numbers, please leave them alone
 APP_VERSION = 0.8.4
 APP_VERSION = 0.8.4
-APP_DEV_VERSION = 0.8.4.14
+APP_DEV_VERSION = 0.8.4.17
 APP_BUILD_NUMBER = 1
 APP_BUILD_NUMBER = 1
 COPYRIGHT_NOTICE =
 COPYRIGHT_NOTICE =
 
 

+ 1 - 1
MedtrumKit

@@ -1 +1 @@
-Subproject commit 3ad0979a3c8fc36c2d48a76da8ea70ef2132943a
+Subproject commit 9914b18c05e9d1064756eaf76a975ea02790e199

+ 14 - 2
Trio/Sources/Services/Alerts/TrioAlertManager.swift

@@ -226,8 +226,18 @@ final class BaseTrioAlertManager: TrioAlertManager, Injectable {
         queue.async {
         queue.async {
             self.liveAlerts.removeValue(forKey: identifier)
             self.liveAlerts.removeValue(forKey: identifier)
         }
         }
-        let responder = queue.sync { responders[identifier.managerIdentifier]?.ref as? AlertResponder }
-        responder?.acknowledgeAlert(alertIdentifier: identifier.alertIdentifier) { error in
+        acknowledgeOnDevice(identifier: identifier)
+    }
+
+    /// Forwards the user's response to the issuing device manager — pump alerts
+    /// need this to also clear the alert on the device itself (e.g. pod beeps).
+    /// Only device managers register as responders (currently just the pump
+    /// manager), so Trio-internal alerts (glucose, not-looping, algorithm)
+    /// never match and bail out here.
+    private func acknowledgeOnDevice(identifier: Alert.Identifier) {
+        guard let responder = queue.sync(execute: { responders[identifier.managerIdentifier]?.ref as? AlertResponder })
+        else { return }
+        responder.acknowledgeAlert(alertIdentifier: identifier.alertIdentifier) { error in
             if let error = error {
             if let error = error {
                 debug(.service, "AlertManager ack failed for \(identifier.value): \(error)")
                 debug(.service, "AlertManager ack failed for \(identifier.value): \(error)")
             }
             }
@@ -364,6 +374,8 @@ final class BaseTrioAlertManager: TrioAlertManager, Injectable {
 
 
 extension BaseTrioAlertManager: TrioModalAlertResponder, TrioUserNotificationAlertResponder {
 extension BaseTrioAlertManager: TrioModalAlertResponder, TrioUserNotificationAlertResponder {
     func requestSnooze(identifier: Alert.Identifier, duration: TimeInterval) {
     func requestSnooze(identifier: Alert.Identifier, duration: TimeInterval) {
+        // Dismissal is the user's response — ack device-issued alerts at the PM layer too.
+        acknowledgeOnDevice(identifier: identifier)
         let untilDate = duration > 0 ? Date().addingTimeInterval(duration) : .distantPast
         let untilDate = duration > 0 ? Date().addingTimeInterval(duration) : .distantPast
         if let glucoseType = GlucoseAlertType(slug: identifier.alertIdentifier) {
         if let glucoseType = GlucoseAlertType(slug: identifier.alertIdentifier) {
             broadcaster.notify(GlucoseSnoozeObserver.self, on: .main) { (observer: GlucoseSnoozeObserver) in
             broadcaster.notify(GlucoseSnoozeObserver.self, on: .main) { (observer: GlucoseSnoozeObserver) in

+ 27 - 1
Trio/Sources/Views/SnoozeAlertsSheetView.swift

@@ -26,7 +26,16 @@ struct SnoozeAlertsSheetView: View {
                             ))
                             ))
                                 .font(.headline)
                                 .font(.headline)
                         }
                         }
-                    }.listRowBackground(Color.chart)
+                        .swipeActions(edge: .trailing, allowsFullSwipe: true) {
+                            endSnoozeAction
+                        }
+                        .listRowBackground(Color.chart)
+                    } footer: {
+                        HStack {
+                            Image(systemName: "hand.draw.fill").foregroundStyle(.primary)
+                            Text("Swipe left to end snooze.")
+                        }
+                    }
                 }
                 }
                 Section(footer: Text(
                 Section(footer: Text(
                     "Pick a duration to mute every Trio alarm. Critical alerts (e.g. occlusion, urgent low) still pierce the snooze."
                     "Pick a duration to mute every Trio alarm. Critical alerts (e.g. occlusion, urgent low) still pierce the snooze."
@@ -62,6 +71,15 @@ struct SnoozeAlertsSheetView: View {
         }
         }
     }
     }
 
 
+    private var endSnoozeAction: some View {
+        Button(role: .destructive) {
+            endSnooze()
+        } label: {
+            Label("End Snooze", systemImage: "alarm.waves.left.and.right.fill")
+        }
+        .tint(.red)
+    }
+
     private func applySnooze(_ duration: TimeInterval) {
     private func applySnooze(_ duration: TimeInterval) {
         let trioAlertManager = resolver.resolve(TrioAlertManager.self)
         let trioAlertManager = resolver.resolve(TrioAlertManager.self)
         Task { @MainActor in
         Task { @MainActor in
@@ -70,4 +88,12 @@ struct SnoozeAlertsSheetView: View {
             isPresented = false
             isPresented = false
         }
         }
     }
     }
+
+    private func endSnooze() {
+        let trioAlertManager = resolver.resolve(TrioAlertManager.self)
+        Task { @MainActor in
+            await trioAlertManager?.applySnooze(for: 0)
+            snoozeUntilDate = Date().addingTimeInterval(0)
+        }
+    }
 }
 }